package com.yhx.share.thisShare;


import com.alibaba.fastjson.JSON;
import com.yhx.security.boc.StreamUtil;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang.StringUtils;


import javax.crypto.spec.SecretKeySpec;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StringWriter;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.*;


public class Sha1WithRsaUtil {
    private final static String SIGN_TYPE_RSA = "RSA";
    private final static String SIGN_ALGORITHMS = "SHA256withRSA";
    private final static String CHARSETTING = "UTF-8";

    /**
     * X509EncodedKeySpec
     * 获取私钥PKCS8格式（需base64）
     * @param algorithm
     * @param priKey
     * @return PrivateKey
     * @throws Exception
     */
    public static PrivateKey getPrivateKeyFromPKCS8(String algorithm, String priKey) throws Exception {
        if (algorithm == null || "".equals(algorithm) || priKey == null || "".equals(priKey))
            return null;

        KeyFactory keyFactory = KeyFactory.getInstance(algorithm);

        byte[] encodedKey = StreamUtil.readText(new ByteArrayInputStream(priKey.getBytes())).getBytes();
        encodedKey = Base64.decodeBase64(priKey.getBytes());
        SecretKeySpec keySpec = new SecretKeySpec(encodedKey, SIGN_TYPE_RSA);
        return keyFactory.generatePrivate(keySpec);
    }

    /**
     * 通过证书获取公钥（需BASE64，X509为通用证书标准）
     * @param algorithm
     * @param pubKey
     * @return PublicKey
     * @throws Exception
     */
    public static PublicKey getPublicKeyFromX509(String algorithm, String pubKey) throws Exception {

        if (algorithm == null || "".equals(algorithm) || pubKey == null || "".equals(pubKey))
            return null;

        KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
        StringWriter writer = new StringWriter();
        StreamUtil.io(new InputStreamReader(new ByteArrayInputStream(pubKey.getBytes())), writer);

        byte[] encodeByte = //writer.toString().getBytes();
        encodeByte = Base64.decodeBase64(pubKey.getBytes());
        SecretKeySpec keySpec = new SecretKeySpec(encodeByte, SIGN_TYPE_RSA);
        return keyFactory.generatePublic(keySpec);
    }

    /**
     * 使用私钥对字符进行签名
     * @param plain  内容体
     * @param prikey  私钥
     * @return String
     * @throws Exception
     */
    public static String sign(String plain, String prikey,PrivateKey privatekey) throws Exception {
        if (plain == null || "".equals(plain) )
            return null;

       // PrivateKey privatekey = getPrivateKeyFromPKCS8(SIGN_TYPE_RSA, prikey);
        //实例化对象
        Signature signature = Signature.getInstance(SIGN_ALGORITHMS);
        //初始化对象
        signature.initSign(privatekey);
        //更新数据
        signature.update(plain.getBytes(CHARSETTING));
        //获取签名
        byte[] signed = signature.sign();

        return new String(Base64.encodeBase64(signed));
    }

    /**
     * 将内容体、签名信息、及对方公钥进行验签
     * @param plain  内容体
     * @param sign   签名信息
     * @param pubkey  对方公钥
     * @return boolean
     * @throws Exception
     */
    public static boolean virefy(String plain, String sign, String pubkey,PublicKey publicKey) throws Exception {
        if (plain == null || "".equals(plain) || sign == null || "".equals(sign) )
            return false;

       // PublicKey publicKey = getPublicKeyFromX509(SIGN_TYPE_RSA, pubkey);
        Signature signature = Signature.getInstance(SIGN_ALGORITHMS);
        signature.initVerify(publicKey);
        signature.update(plain.getBytes(CHARSETTING));

        return signature.verify(Base64.decodeBase64(sign.getBytes()));
    }
    public static KeyPair genKeyPair1() throws NoSuchAlgorithmException, IOException {
        // KeyPairGenerator类用于生成公钥和私钥对，基于RSA算法生成对象
        KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
        // 初始化密钥对生成器，密钥大小为1024位
        keyPairGen.initialize(1024,new SecureRandom());
        // 生成一个密钥对，保存在keyPair中
        KeyPair keyPair = keyPairGen.generateKeyPair();
        RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();   // 得到私钥
        RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();  // 得到公钥
       String publicKeyString = new String(Base64.encodeBase64(publicKey.getEncoded()));
        // 得到私钥字符串
        String privateKeyString = new String(Base64.encodeBase64((privateKey.getEncoded())));

        System.out.println(privateKeyString);
        System.out.println(publicKeyString);
        // 将公钥和私钥保存到Map
        /*
        keyMap.put(0,publicKeyString);  //0表示公钥
        keyMap.put(1,privateKeyString);  //1表示私钥*/
        return keyPair;
    }
    /**
     * 测试
     * @param args
     * @throws Exception
     */

    public static void main(String[] args) throws Exception {
        KeyPair keyPair=genKeyPair1();
        String signStr="zhangsanlisi";
        String sign = sign(signStr,"", keyPair.getPrivate());
        //System.out.println("签名="+sign);
        //System.out.println(virefy(signStr, sign,"", keyPair.getPublic()));
    }
}